package com.loong.tool.lang;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

/**
 * 请求处理工具
 * 
 * @author 张成轩
 */
public class Requests {

	/** 未知标识 */
	public static final String OTHER = "Other";

	/**
	 * 浏览器判别
	 *
	 * @author 张成轩
	 */
	public enum Browser {

		/** IE */
		IE("IE", "MSIE [^;) ]*", "[ ;]", -1, 0),
		/** IE 11+ */
		IE_11U("IE", "rv[ :].*like Gecko", "[ :)]", 1, 0),
		/** Edge */
		Edge("Edge", "Edge/[^;) ]*", "[ /]", -1, 2),
		/** 火狐 */
		Firefox("Firefox", "Firefox/[^;) ]*", "[ /]", -1, 1),
		/** Chrome */
		Chrome("Chrome", "Chrome/[^;) ]*", "[ /]", -1, 1),
		/** Safari */
		Safari("Safari", "Version/[^;) ]*( Mobile[^;) ]*)? Safari/[^;) ]*", "[ /]", 1, 0),
		/** Opera */
		Opera("Opera", "Opera/.*Presto/[^;) ]* Version/[^;) ]*", "[ /]", -1, 1),
		/** Opera 10- */
		Opera_10L("Opera", "Opera[ /][^;) ]*", "[ /]", -1, 0);

		private String name;
		private String regex;
		private String split;
		private int index;
		private int priority;

		/**
		 * @param name 名称
		 * @param regex 匹配正则表达式
		 * @param split 版本号分隔符
		 * @param index 版本号位置，-1代表末尾
		 * @param priority 优先级
		 */
		private Browser(String name, String regex, String split, int index, int priority) {

			this.name = name;
			this.regex = regex;
			this.index = index;
			this.split = split;
			this.priority = priority;
		}
	}

	/**
	 * 操作系统判别
	 *
	 * @author 张成轩
	 */
	public enum OS {

		/** Windows 95 */
		Win95("Windows 95", "Windows 95", 1),
		/** Windows 98 */
		Win98("Windows 98", "Windows 98", 1),
		/** Windows 2000 */
		Win2000("Windows 2000", "(Windows NT 5.0)|(Windows 2000)", 1),
		/** Windows XP */
		WinXP("Windows XP", "(Windows NT 5.1)|(Windows XP)", 1),
		/** Windows 2003 */
		Win2003("Windows 2003", "(Windows NT 5.2)|(Windows 2003)", 1),
		/** Windows Vista */
		WinVista("Windows Vista", "(Windows NT 6.0)|(Windows Vista)", 1),
		/** Windows 7 */
		Win7("Windows 7", "(Windows NT 6.1)|(Windows 7)", 1),
		/** Windows 8 */
		Win8("Windows 8", "(Windows NT 6.2)|(Windows 8)", 1),
		/** Windwos 10 */
		Win10("Windows 10", "(Windows NT 10.0)|(Windows 10)", 1),
		/** Windows Phone */
		WinPhone("Windows Phone", "Windows Phone", 1),
		/** Windows */
		WinOther("Windows ?", "Windows", 0),
		/** Linux */
		Linux("Linux", "Linux", 0),
		/** Linux RedHat */
		RedHat("RedHat", "RedHat", 1),
		/** Linux Ubuntu */
		Ubuntu("Ubuntu", "Ubuntu", 1),
		/** iPhone */
		iPhone("iPhone", "iPhone", 1),
		/** iPod */
		iPod("iPod", "iPod", 1),
		/** iPad */
		iPad("iPad", "iPad", 1),
		/** 苹果 */
		Mac("Mac", "Mac", 0),
		/** 安卓 */
		Android("Android", "Android", 1),
		/** 塞班 */
		Symbian("Symbian", "Symbian", 1);

		private String name;
		private String regex;
		private int priority;

		/**
		 * @param name 名称
		 * @param regex 匹配正则表达式
		 * @param priority 优先级
		 */
		private OS(String name, String regex, int priority) {

			this.name = name;
			this.regex = regex;
			this.priority = priority;
		}
	}

	/**
	 * 获取客户端ip
	 * 
	 * @param request 请求
	 * @return 客户端ip
	 */
	public static String getIp(HttpServletRequest request) {

		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
			ip = request.getHeader("Proxy-Client-IP");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
			ip = request.getHeader("WL-Proxy-Client-IP");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
			ip = request.getRemoteAddr();
		return ip;
	}

	/**
	 * 获取客户端环境
	 * 
	 * @param request 请求
	 * @return 客户端环境
	 */
	public static Env getEnv(HttpServletRequest request) {

		return getEnv(request.getHeader("User-Agent"));
	}

	/**
	 * 获取客户端环境
	 * 
	 * @param userAgent userAgent
	 * @return 客户端环境
	 */
	public static Env getEnv(String userAgent) {

		if (userAgent == null) {
			return null;
		}

		Browser browser = null;
		String browserVersion = null;
		OS os = null;

		// 判断浏览器
		Browser[] bs = Browser.values();
		for (Browser b : bs) {
			Pattern pattern = Pattern.compile(b.regex);
			Matcher matcher = pattern.matcher(userAgent);
			// 校验浏览器标志
			if (matcher.find()) {
				// 判断优先级
				if (browser != null && browser.priority >= b.priority) {
					continue;
				}
				browser = b;
				String[] ss = matcher.group().split(b.split);

				int index = b.index < 0 ? ss.length + b.index : b.index;
				if (index < ss.length && index >= 0) {
					browserVersion = ss[index];
				} else {
					browserVersion = null;
				}
			}
		}

		// 判断操作系统
		OS[] oss = OS.values();
		for (OS o : oss) {
			Pattern pattern = Pattern.compile(o.regex);
			Matcher matcher = pattern.matcher(userAgent);
			// 校验浏览器标志
			if (matcher.find()) {
				// 判断优先级
				if (os != null && os.priority >= o.priority) {
					continue;
				}
				os = o;
			}
		}

		// 封装返回对象
		Env env = new Env();
		if (browser != null) {
			env.browser = browser.name;
			env.browser_version = browserVersion;
		} else {
			env.browser = OTHER;
		}
		if (os != null) {
			env.os = os.name;
		} else {
			env.os = OTHER;
		}
		env.env = userAgent;
		return env;
	}

	/**
	 * 客户端环境
	 *
	 * @author 张成轩
	 */
	public static class Env {

		private String os;
		private String browser;
		private String browser_version;
		private String env;

		/**
		 * @return 操作系统
		 */
		public String getOs() {

			return os;
		}

		/**
		 * @return 浏览器
		 */
		public String getBrowser() {

			return browser;
		}

		/**
		 * @return 浏览器版本
		 */
		public String getBrowserVersion() {

			return browser_version;
		}

		/**
		 * @return 请求环境
		 */
		public String getEnv() {

			return env;
		}
	}
}
